import json
import time

from utils.base import BaseSerializer
from django_celery_beat.models import PeriodicTask, CrontabSchedule
from rest_framework.validators import ValidationError
from rest_framework.serializers import ModelSerializer
from apps.suites.models import Suite, CrontabTask

from rest_framework import serializers


class SuiteSerializer(BaseSerializer):

    class Meta:
        model = Suite
        fields = '__all__'


class CrontabTaskSerializer(BaseSerializer):
    suite_name = serializers.CharField(source='suite.name', read_only=True)
    env_name = serializers.CharField(source='env.name', read_only=True)
    periodic_task_name = serializers.CharField(source='periodic_task.name', read_only=True)

    class Meta:
        model = CrontabTask
        fields = '__all__'

    def validate_crontab(self, value):
        value = value.strip()
        if len(value.split(' ')) != 5:
            raise ValidationError('定时策略格式不正确')
        return value

    def get_periodic_task(self):

        if self.periodic_task:
            return self.periodic_task

    def get_crontab(self, crontab_value):
        minute, hour, day_of_week, day_of_month, month_of_year = crontab_value.split(' ')
        queryset = CrontabSchedule.objects.filter(
            minute=minute,
            hour=hour,
            day_of_week=day_of_week,
            day_of_month=day_of_month,
            month_of_year=month_of_year,
        )
        if queryset:
            crontab = queryset.first()
        else:
            crontab = CrontabSchedule.objects.create(
                minute=minute,
                hour=hour,
                day_of_week=day_of_week,
                day_of_month=day_of_month,
                month_of_year=month_of_year,
            )
        return crontab

    def get_kwargs(self, validated_data):
        return {
            'suite_id': validated_data['suite'] if isinstance(validated_data['suite'], int) else validated_data['suite'].id,
            'env_id': validated_data['env'] if isinstance(validated_data['env'], int) else validated_data['env'].id,
            'user_id': self.context['user'].id
        }

    def create(self, validated_data):
        instance = super().create(validated_data)
        name = str(time.time()) + '_' + str(self.context['user'].id)

        instance.periodic_task = PeriodicTask.objects.create(name=name,
                                                             crontab=self.get_crontab(validated_data['crontab']),
                                                             enabled=validated_data['enabled'],
                                                             task='core.run_suite.run_suite',
                                                             kwargs=json.dumps(self.get_kwargs(validated_data)))
        instance.save()
        return instance

    def update(self, instance, validated_data):
        instance = super().update(instance, validated_data)
        periodic_task_obj = PeriodicTask.objects.get(id=validated_data['periodic_task'].id)
        periodic_task_obj.kwargs = json.dumps(self.get_kwargs(validated_data))
        periodic_task_obj.enabled = validated_data['enabled']
        periodic_task_obj.crontab = self.get_crontab(validated_data['crontab'])
        periodic_task_obj.save()
        return instance


